import Vue from 'vue'
import { createApp } from './app'
import { createClientHttp } from './http'
import { getToken } from '@/utils/auth'
import NProgress from 'nprogress' // Progress 进度条
import 'nprogress/nprogress.css'// Progress 进度条样式
import { setGlobalData } from '@/utils/global_data'

// a global mixin that calls `asyncData` when a route component's params change
Vue.mixin({
  beforeRouteUpdate (to, from, next) {
    const { asyncData } = this.$options
    if (asyncData) {
      asyncData({
        store: this.$store,
        route: to
      }).then(next).catch(next)
    } else {
      next()
    }
  }
})

const { app, router, store } = createApp(createClientHttp())

// prime the store with server-initialized state.
// the state is determined during SSR and inlined in the page markup.
if (window.__INITIAL_STATE__) {
  store.replaceState(window.__INITIAL_STATE__)
}

// save store and router
setGlobalData('store', store)
setGlobalData('router', router)

// wait until router has resolved all async before hooks and async components...
router.onReady(() => {
  // Add router hook for handling asyncData.
  // Doing it after initial route is resolved so that we don't double-fetch
  // the data that we already have. Using router.beforeResolve() so that all
  // async components are resolved.
  router.beforeResolve((to, from, next) => {
    const matched = router.getMatchedComponents(to)
    const prevMatched = router.getMatchedComponents(from)
    let diffed = false
    const activated = matched.filter((c, i) => {
      return diffed || (diffed = (prevMatched[i] !== c))
    })
    const asyncDataHooks = activated.map(c => c.asyncData).filter(_ => _)
    if (!asyncDataHooks.length) {
      return next()
    }

    NProgress.start()

    Promise.all(asyncDataHooks.map(hook => hook({ store, route: to })))
      .then(() => {
        NProgress.done()
        next()
      })
      .catch(next)
  })

  router.beforeEach((to, from, next) => {
    NProgress.start()
    if (getToken()) {
      if (to.path === '/login') {
        next({path: '/home'})
        NProgress.done()
      } else {
        if (to.meta.noLogin) {
          next()
        } else {
          // if (!store.state.user.isLogin) {
          //   store.dispatch('getUserInfo').then(res => {
          //     next()
          //   }).catch(() => {
          //     Message.error('验证失败，请重新登录')
          //     next({ path: '/login' })
          //   })
          // } else {
          //   next()
          // }
        }
      }
    } else {
      if (to.meta.noLogin) {
        next()
      } else {
        next('/login')
        NProgress.done()
      }
    }
  })

  router.afterEach((route) => {
    NProgress.done() // 结束Progress
  })

  // actually mount to DOM
  app.$mount('#app')
})
